/*******************************************************************************
 * Copyright (c) 2011 Irineu Martins de Lima Moura (imlm2).
 * This file is part of JBeat.
 * 
 *     JBeat is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     JBeat is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Lesser General Public License for more details.
 * 
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with JBeat.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     Irineu Martins de Lima Moura (imlm2) - initial API and implementation
 ******************************************************************************/
package br.ufpe.cin.imlm2.util;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class BuildClasspath {

	private static final String JARS_COMMAND = "--jars:";
	private static final String JARS_RECURSIVE_COMMAND = "--jars-rec:";
	private static final String PROJECT_FILE_COMMAND = "--cpFile:";
	
	private static void printUsage(){
		System.out.println("Usage:" +
				"jars:DIR  Scans for jars in directory DIR"+ SystemProperties.LINE_SEPARATOR +
				"jars-rec:DIR  Scans for jars in DIR and recursively in all directories of DIR" + SystemProperties.FILE_SEPARATOR +
				"cpFile:FILE  Parses an Eclipse project classpath FILE for classpath entries"+ SystemProperties.FILE_SEPARATOR);
		
	}
	
	/**
	 * @param args
	 * @throws IOException 
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 */
	public static void main(String[] args) throws IOException, ParserConfigurationException, SAXException {
		if(args.length > 0) {
			String outputFilePath = "classpath.txt";

			List<String> ps = new ArrayList<String>();
			for (int i = 0; i < args.length; i++) {
				if(args[i].startsWith(JARS_COMMAND)){
					String arg = args[i].replaceFirst(JARS_COMMAND, "");
					File f = new File(arg);
					ps.addAll(buildFromCPEntries(f,false));
				} else if(args[i].startsWith(JARS_RECURSIVE_COMMAND)){
					String arg = args[i].replaceFirst(JARS_RECURSIVE_COMMAND, "");
					File f = new File(arg);
					ps.addAll(buildFromCPEntries(f,true));
				} else if(args[i].startsWith(PROJECT_FILE_COMMAND)){
					String arg = args[i].replaceFirst(PROJECT_FILE_COMMAND, "");
					File f = new File(arg);
					ps.addAll(buildFromProjectFile(f));
				} else if(i ==  args.length - 1){ 
					outputFilePath = args[i];
				} else {
					throw new IllegalArgumentException("Illegal option specified");
				}
			}

			FileWriter fw = new FileWriter(outputFilePath);
			StringBuffer sb = new StringBuffer();
			for (String string : ps) {
				sb.append("\""+string + "\"" + SystemProperties.PATH_SEPARATOR);
			}
			sb.deleteCharAt(sb.length() - 1);
			fw.append(sb);
			fw.flush();
		} else {
			printUsage();
		}

	}

	public static List<String> buildFromCPEntries(File searchPath,boolean recursively){
		CPEntryFinder fv = new CPEntryFinder(recursively);
		fv.findJars(searchPath);
		return fv.getPaths();
	}

	public static List<String> buildFromProjectFile(File projectFile) throws ParserConfigurationException, SAXException, IOException{
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		List<String> caminhos = new ArrayList<String>();
		String diretorioPai = projectFile.getParent() + SystemProperties.FILE_SEPARATOR;

		Document doc = db.parse(projectFile);
		NodeList entradas = doc.getDocumentElement().getElementsByTagName("classpathentry");

		for (int i = 0; i < entradas.getLength(); i++) {
			Element e = (Element) entradas.item(i);
			String exclude = e.getAttribute("excluding");
			if(exclude == null || exclude.equals("")) {
				String cam = e.getAttribute("path");
				caminhos.add(diretorioPai + cam);
			}
		}
		return caminhos;
	}

}
